# include "TurglemLemmatizer.hpp"

# include <turglem/russian/adapter.h>
# include <turglem/english/adapter.h>

# include <stdexcept>
# include <iostream>

CCHAR_P TurglemLemmatizer::pRussianDictAutoPath = "/russian/dict_russian.auto";
CCHAR_P TurglemLemmatizer::pPredictionRussianAutoPath = "/russian/prediction_russian.auto";
CCHAR_P TurglemLemmatizer::pParadigmsRussianBinPath = "/russian/paradigms_russian.bin";    
CCHAR_P TurglemLemmatizer::pEnglishDictAutoPath = "/english/dict_english.auto";
CCHAR_P TurglemLemmatizer::pPredictionEnglishAutoPath = "/english/prediction_english.auto";
CCHAR_P TurglemLemmatizer::pParadigmsEnglishBinPath = "/english/paradigms_english.bin";

TurglemLemmatizer::TurglemLemmatizer(CCHAR_P pTurglemPath)
{
	const STLW::string sTurglemPath(pTurglemPath);
	const STLW::string sRussianDictAutoPath = sTurglemPath + STLW::string(pRussianDictAutoPath);
	const STLW::string sPredictionRussianAutoPath = sTurglemPath + STLW::string(pPredictionRussianAutoPath);
	const STLW::string sParadigmsRussianBinPath = sTurglemPath + STLW::string(pParadigmsRussianBinPath);
	const STLW::string sEnglishDictAutoPath = sTurglemPath + STLW::string(pEnglishDictAutoPath);
	const STLW::string sPredictionEnglishAutoPath = sTurglemPath + STLW::string(pPredictionEnglishAutoPath);
	const STLW::string sParadigmsEnglishBinPath = sTurglemPath + STLW::string(pParadigmsEnglishBinPath);
	
	int iErrNo = 0;
	int iWhat = 0;
	
	oRusLem = turglem_load(sRussianDictAutoPath.c_str(), sPredictionRussianAutoPath.c_str(), 
						   sParadigmsRussianBinPath.c_str(), &iErrNo, &iWhat);
	if (0 != iErrNo)
	{
		throw std::runtime_error(turglem_error_what_string(iWhat));
	}
	
	oEngLem = turglem_load(sEnglishDictAutoPath.c_str(), sPredictionEnglishAutoPath.c_str(), 
						   sParadigmsEnglishBinPath.c_str(), &iErrNo, &iWhat);
	
	if (0 != iErrNo)
	{
		turglem_close(oRusLem);
		throw std::runtime_error(turglem_error_what_string(iWhat));
	}
}

TurglemLemmatizer::~TurglemLemmatizer() throw()
{
	turglem_close(oRusLem);
	turglem_close(oEngLem);
}

STLW::vector<STLW::string> TurglemLemmatizer::FirstForms(CCHAR_P sWord, const UINT_32 & iWordLength, 
														 const UINT_32 & iUseParadigms)
{
	UINT_32 bIsRussian = IsRussian(sWord, iWordLength);
	MAFSA_letter sMAFSALetter[1024];
	ssize_t iLetterSize = 0;
	
	if (bIsRussian)
	{
		iLetterSize = RUSSIAN_conv_binary_to_letter_utf8(sWord, iWordLength, sMAFSALetter, 1024);
	}
	else
	{
		iLetterSize = ENGLISH_conv_binary_to_letter_utf8(sWord, iWordLength, sMAFSALetter, 1024);
	}
	
	int aForms[2 * 1024];
	int iFoundForms = turglem_lemmatize(bIsRussian ? oRusLem : oEngLem, sMAFSALetter, iLetterSize, 
										aForms, 1024, bIsRussian ? RUSSIAN_LETTER_DELIM : ENGLISH_LETTER_DELIM, 1);		
										
	STLW::vector<STLW::string> vForms(iFoundForms);
	//this should not happen, but...
	if (iFoundForms == 0)
	{
		vForms.push_back(STLW::string(sWord, iWordLength));
	}

	MAFSA_letter oDestLetter[1024];
	char oBinary[1024];
	for (int iForm = 0; iForm < iFoundForms; ++iForm)
	{
		int iDestSize = 0;
		int iBinaryDestSize = 0;

		if (bIsRussian)
		{
			iDestSize = turglem_build_form(oRusLem, sMAFSALetter, iLetterSize, oDestLetter, 1024, 
										   aForms[2 * iForm], aForms[2 * iForm + 1], 0);
			iBinaryDestSize = RUSSIAN_conv_letter_to_binary_utf8(oDestLetter, iDestSize, oBinary, 1024);
		}
		else
		{
			iDestSize = turglem_build_form(oEngLem, sMAFSALetter, iLetterSize, oDestLetter, 1024, 
										   aForms[2 * iForm], aForms[2 * iForm + 1], 0);
			iBinaryDestSize = ENGLISH_conv_letter_to_binary_utf8(oDestLetter, iDestSize, oBinary, 1024);
		}
	
		vForms[iForm] = STLW::string(oBinary, iBinaryDestSize);
	}	
	
	return vForms;
}
